/**
 * Copyright [2019] [LiBo/Alex of copyright liboware@gmail.com ]
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.monitor.profile.loader;

import com.hyts.monitor.profile.config.ConfigKey;
import com.hyts.monitor.profile.config.ProfilerConfig;
import com.hyts.monitor.profile.error.ProfilerException;
import com.hyts.monitor.profile.model.Connector;
import com.hyts.monitor.profile.model.Filter;
import com.hyts.monitor.profile.model.Profiler;
import lombok.Getter;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @project-name:coffice-toolbox
 * @package-name:com.hyts.monitor.profile.loader
 * @author:LiBo/Alex
 * @create-date:2019-08-08 14:03
 * @copyright:libo-alex4java
 * @email:liboware@gmail.com
 * @description: process arg > env > config > db > other
 */
public abstract class AbtractProfilerLoader implements ProfilerLoader{


    @Getter
    protected Profiler profiler = new Profiler();

    /**
     * change the useDefaultConfig state value
     */
    public abstract boolean preCheckUseDefault();

    @Getter
    Map<String,List<String>> configModuleKey = new HashMap<>();


    /**
     * 配置读取操作的出口服务方法
     */
    @Override
    public Profiler loadProfilerConfig(){
        //加载多个module服务模型配置key参数集合对象
        loadMultiModuleConfigKey();
        if(!preCheckUseDefault()) {
            loadCommandConfig(ConfigKey.COMMAND,configModuleKey.get(ConfigKey.COMMAND.toLower()));
            loadAttributeConfig(ConfigKey.ATTRIBUTE,configModuleKey.get(ConfigKey.ATTRIBUTE.toLower()));
            loadConnectorConfig(ConfigKey.CONNECTOR,configModuleKey.get(ConfigKey.CONNECTOR.toLower()));
            loadFilterConfig(ConfigKey.FILTER,configModuleKey.get(ConfigKey.FILTER.toLower()));
            loadScopeConfig(ConfigKey.SCOPE,configModuleKey.get(ConfigKey.SCOPE.toLower()));
        }
        return profiler;
    }

    /**
     * 加载module模型配置key服务属性字段
     * ConfigKey枚举字段的相关属性参数-module类对象
     */
    protected AbtractProfilerLoader loadMultiModuleConfigKey(){
        //配置多，模块
        try {
            ConfigKey[] configKeys = ConfigKey.values();
            for (ConfigKey configKey : configKeys) {
                PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(configKey.getClazz()).getPropertyDescriptors();
                configModuleKey.put(configKey.name().toLowerCase(),
                        Arrays.stream(propertyDescriptors).flatMap(param -> Stream.of(param.getName())).
                                filter(param2->!param2.equals("class")).
                        collect(Collectors.toList()));
            }
        }catch (IntrospectionException e){
            throw new ProfilerException(e);
        }
        return this;
    }

}
